//
// itertool - a polynormial and type-safe iterator framework in C++.
//
// Copyright (c) 2021-2025 Feng Cong
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
// https://opensource.org/licenses/MIT

#include <itertool/iter/filter.h>

#include "itertool_test.h"

TEST_SUITE("Filter") {
  const int kLimit = 10;  // 0..9

  inline bool IsOdd(int x) { return x & 1; }

  TEST_CASE("Filter") {
    auto it = itertool::Filter(itertool_test::NaturalNumber(kLimit), &IsOdd);

    SUBCASE("should only yield things predicate says true") {
      int i = 0;
      for (auto val : it) {
        CHECK(IsOdd(val));
        i++;
      }
      CHECK_EQ(i, kLimit / 2);
    }
  }

  TEST_CASE("FilterFalse") {
    auto it =
        itertool::FilterFalse(itertool_test::NaturalNumber(kLimit), &IsOdd);

    SUBCASE("should only yield things predicate says false") {
      int i = 0;
      for (auto val : it) {
        CHECK_FALSE(IsOdd(val));
        ++i;
      }
      CHECK_EQ(i, kLimit / 2);
    }
  }

  TEST_CASE("Compatible signatures of func should work") {
    auto func_1 = [](int x) { return x; };
    itertool::Filter(itertool_test::NaturalNumber(kLimit), func_1);

    auto func_2 = [](double x) { return x > 0; };
    itertool::Filter(itertool_test::NaturalNumber(kLimit), func_2);

    auto func_3 = [](double x, bool val = false) { return x > 0 && val; };
    itertool::Filter(itertool_test::NaturalNumber(kLimit), func_3);
  }

#if 0
  TEST_CASE("Requirement test") {
    auto bad_func = []() { return false; };
    itertool::Filter(itertool_test::NaturalNumber(kLimit), bad_func);
  }
#endif
}